package com.agileai.bpm.interceptor.rest;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;
import org.codehaus.jettison.json.JSONObject;
import org.mvel2.templates.TemplateRuntime;

import com.agileai.bpm.common.BPMConstants;
import com.agileai.bpm.common.VariableInterpreter;
import com.agileai.bpm.domain.define.Activity;
import com.agileai.bpm.domain.running.ActivityInstance;
import com.agileai.bpm.domain.running.ProcessInstance;
import com.agileai.bpm.domain.running.ProcessVariableInstance;
import com.agileai.bpm.interceptor.BaseInterceptor;
import com.agileai.bpm.model.InterceptorModelDocument.InterceptorModel;
import com.agileai.bpm.model.RestInvokerType;
import com.agileai.hotweb.common.HttpClientHelper;
import com.agileai.util.StringUtil;

public class RestInvokerInterceptor extends BaseInterceptor{
	private String httpURL = null;
	private String requestJson = null;
	
	public RestInvokerInterceptor(InterceptorModel model,Activity activity){
		this.type = BaseInterceptor.Type.RestInvoker;
		this.isSynchronous = model.getSynchronous();
		this.variableCode = model.getVariableCode();
		this.varExpression = model.getVarExpression();
		
		RestInvokerType restInvokerType = model.getRestInvoker();
		httpURL = restInvokerType.getHttpURL();
		requestJson = restInvokerType.getRequestJson();
	}
	
	@SuppressWarnings("rawtypes")
	public void doIntercept(ActivityInstance activityInstance) throws Exception  {
		HttpClientHelper httpClientHelper = new HttpClientHelper();
		ProcessInstance processInstance = activityInstance.getProcessInstance();
		String requestContent = VariableInterpreter.replaceVariables(this.requestJson, activityInstance);
		HttpEntity httpEntity = new StringEntity(requestContent, "utf-8");
		String realHttpURL = VariableInterpreter.replaceVariables(this.httpURL, activityInstance);
		if (this.isSynchronous){
			String responseText = httpClientHelper.retrievePostReponseText(realHttpURL, httpEntity);
			if (BPMConstants.EmbedVariable.targetUserCodes.equals(variableCode)){
				Map vars = jsonObjectToMap(responseText);
				String value = (String)TemplateRuntime.eval(varExpression, vars);
				if (StringUtil.isNotNullNotEmpty(value)){
					String[] userArray = value.split(",");
					for (int i=0;i < userArray.length;i++){
						String userCode = userArray[i];
						activityInstance.getTargetUserCodeList().add(userCode);
					}
				}
			}else{
				ProcessVariableInstance processVariableInstance = processInstance.getVariableInstances().get(this.variableCode);
				if (processVariableInstance != null){
					Map vars = jsonObjectToMap(responseText);
					String value = (String)TemplateRuntime.eval(varExpression, vars);
					processVariableInstance.setValue(value);
				}
			}
		}else{
			httpClientHelper.retrievePostReponseText(realHttpURL, httpEntity);
		}
	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map jsonObjectToMap(String responseText) throws Exception{
		Map map = new HashMap();
		JSONObject json = new JSONObject(responseText);
		Iterator keys = json.keys();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String value = json.get(key).toString();
			if (value.startsWith("{") && value.endsWith("}")) {
				map.put(key, jsonObjectToMap(value));
			} else {
				map.put(key, value);
			}
		}
		return map;
	}
	public void handleException(ActivityInstance activityInstance,Exception ex) {
		ex.printStackTrace();
	}
}
